//
//  Inode.cpp
//  LearningOops
//
//  Created by Swetha Patnala on 4/14/13.
//  Copyright (c) 2013 Swetha Patnala. All rights reserved.
//

#include <cstdio>
#include "Inode.h"
#include "File_System_Manager.h"
using namespace std;

Inode::Inode() {
    inode = NULL;
}

Inode::Inode(int num ,char* name) {
    
    File_System_Manager *file;
    file =  File_System_Manager::getInstance();
    
    
    inode = new inode_structure;
    inode->inode_number = num;
    file->increment_inodecounter();
    inode->file_name = name;
    inode->mode = (char*)"rwx";
    inode->size_of_file = DATABLOCK_SIZE;
    inode->number_of_blocks_allocated_to_file = 0;
    inode->userid = 1;
    inode->groupid =1;
    
    /*
     vector <int> inode_vector;
     time_t  time_of_creation;
     time_t  last_access_time;
     time_t  last_modification_time;
     
     */
    
    
    
    
    file->assignValueToInodeBitmap(inode->inode_number);
    file->decrement_num_of_unallocated_inodes();
    
    file_descriptor_count = 0;
    
    for(int i = 1 ; i < NUM_OF_FILE_DESCRIPTORS+1 ; i++){
        
        inode->fd[i] = new file_descriptor_table;
        
        inode->fd[i]->fd_number = 0;
        
        
    }
    
    time_t file_creation_time = getCurrentTime();
    set_createTime(file_creation_time);
    set_LastAccessTime(file_creation_time);
    set_ModifiedTime(file_creation_time);
    
    //printInode();
    
}




char* Inode::getName() {
    if (!inode)
        return NULL;
    
    char* name = inode->file_name;
    // cout << "The name of file is "<<name<<endl;
    return name;
}

int Inode::getNum(){
    return inode->inode_number;
}

int Inode::getSizeOfFile(){
    return inode->size_of_file;
}

void Inode::printInode(){
    
    cout << "Inode Number                           :" << inode->inode_number<<endl;
    cout << "Name of the file                       :" << inode->file_name <<endl;
    cout << "Size of file                           :" << inode->size_of_file<<endl;
    cout << "Number of blocks allocated to the file :" <<inode->number_of_blocks_allocated_to_file<<endl;
    cout << "Mode of the file                       :" <<inode->mode <<endl;
    cout << "User Id                                :" << inode->userid <<endl;
    cout << "Group Id                               :" << inode->groupid<<endl;
    cout << "File creation time                     :" ;
    displayTime(inode->time_of_creation);
    //cout <<endl;
    cout << "Time of last access                    :" ;
    displayTime( inode->last_access_time);
    cout << "Time of modification                   :"  ;
    displayTime(inode->last_modification_time);
    
    cout << "--------------------------------------------------" << endl;
    
    //time_t t1 = getCurrentTime();
    //displayTime(t1);
    
    
}

time_t Inode::getCurrentTime(){
    time_t t;
    struct tm *local;
    t =time(NULL);
    local = localtime(&t);
    //cout << asctime(local);
    return t;
    
}

void Inode::set_createTime(time_t t){
    
    inode->time_of_creation = t;
    
    
    
}

void Inode::set_ModifiedTime(time_t t){
    inode->last_modification_time = t;
}



void Inode::set_LastAccessTime(time_t t){
    inode->last_access_time = t;
}

void Inode::displayTime(time_t t){
    struct tm *local;
    local = localtime(&t);
    cout<< asctime(local);
    
}

int Inode::getFreeFileDescriptor(){
    
    for(int i =1 ; i< NUM_OF_FILE_DESCRIPTORS+1 ; i++){
        if( inode->fd[i]->fd_number==0){
            return i;
            
        }
    }
    return -1;
}

int Inode::allocateFileDescriptor(int fd_num){
    
    inode->fd[fd_num]->fd_number = fd_num;
    inode->fd[fd_num]->fd_start = 0;
    inode->fd[fd_num]->fd_current =0 ;
    file_descriptor_count++;
    return 0;
    
}

int Inode::getFileDescriptorCount(){
    return file_descriptor_count;
}


bool Inode::isFileDescriptorAvailable(int fd){
    
    for(int i =1 ; i< NUM_OF_FILE_DESCRIPTORS+1 ; i++){
        if( inode->fd[i]->fd_number==fd){
            return true;
        }
    }
    return false;
}

int Inode::deallocateFileDescriptor(int num){
    
    
    inode->fd[num]->fd_number = 0;
    inode->fd[num]->fd_start = 0;
    inode->fd[num]->fd_current = 0;
    file_descriptor_count--;
    return 0;
    
}
/*
 int Inode::set_Data_Block_num(int data_block_num){
 
 inode->data_block_num = data_block_num;
 return 0;
 }
 
 int Inode::get_Data_Block_num(){
 
 return inode->data_block_num ;
 
 }
 */

inode_structure* Inode::get_inode_structure() {
    return inode;
}


void Inode::addToInodeVector(int datablock_num){
    
    inode->inode_vector.push_back(datablock_num);
}

void Inode::printInodeVector(){
    
    cout << "the datablocks are at : ";
    for(int i =0 ; i< inode->inode_vector.size() ; i++ ){
        cout << inode->inode_vector.at(i);
    }
}

vector <int> Inode::getInodeVector(){
    
    return inode->inode_vector;
    
    
}

void Inode::increment_num_of_datablocks(){
    inode->number_of_blocks_allocated_to_file++;
    inode->size_of_file = inode->size_of_file + 4096 ;
    //cout<<"no of data blocks " << inode->number_of_blocks_allocated_to_file;
}
